package com.zzj.utils;

import lombok.extern.log4j.Log4j2;
import org.apache.tomcat.util.http.fileupload.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Log4j2
@Service
public class FileUtil {

    @Value("${system-params.file-save-path}")
    private String filePath;

    /**
     * files路径
     *
     * @param file
     * @return
     * @throws IOException
     */
    public String upload(MultipartFile file) throws IOException {

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        String fileName = generateUniqueFileName(Objects.requireNonNull(file.getOriginalFilename()));
        // 获取文件的字节数组
        byte[] bytes = file.getBytes();

        File folder = getFolder("/files/" + simpleDateFormat.format(new Date()));
        // 设置文件存储路径
        Path path = Paths.get(folder.getPath(), fileName);

        // 写入文件到指定路径
        Files.write(path, bytes);
        return "/cloudDiskAPI/upload/cloud-disk/files/" + simpleDateFormat.format(new Date()) + "/" + fileName;
    }

    // 生成唯一的文件名
    private String generateUniqueFileName(String originalFileName) {
        // 使用UUID生成唯一的文件名，并保留原始文件的扩展名
        String extension = originalFileName.substring(originalFileName.lastIndexOf('.'));
        return UUID.randomUUID() + extension;
    }

    /**
     * 删除文件
     * /cloudDiskAPI/upload/cloud-disk/files/2023-11-16/nvf4ho3yx8.mp4
     * or
     * /files/2023-11-16/nvf4ho3yx8.mp4
     *
     * @param pathName
     * @return
     */
    public boolean removeFile(String pathName) {
        String delimiter = "/cloudDiskAPI/upload/cloud-disk";
        if (pathName.contains(delimiter)) {
            pathName = pathName.split(delimiter)[1];
        }
        File file = new File(filePath + pathName);
        if (file.exists()) {
            if (file.delete()) {
                log.info("文件" + file.getAbsolutePath() + "已删除");
                return true;
            } else {
                log.error("文件删除失败");
                return false;
            }
        } else {
            log.error("文件不存在");
            return true;
        }
    }

    /**
     * 删除文件夹
     * /cloudDiskAPI/upload/cloud-disk/tmp/文件夹
     * or
     * /tmp/文件夹
     *
     * @param pathName /tmp/文件夹
     * @return
     */
    public boolean removeFolder(String pathName) {
        String delimiter = "/cloudDiskAPI/upload/cloud-disk";
        if (pathName.contains(delimiter)) {
            pathName = pathName.split(delimiter)[1];
        }
        File folder = new File(filePath + pathName);
        if (!folder.exists()) {
            log.error("文件夹不存在：" + folder.getAbsolutePath());
            return true;
        }
        try {
            FileUtils.deleteDirectory(folder);
            log.info("文件夹已删除：" + folder.getAbsolutePath());
            return true;
        } catch (IOException e) {
            log.error("文件夹删除失败：" + folder.getAbsolutePath(), e);
            return false;
        }
    }

    /**
     * 获取文件
     *
     * @param pathName
     * @return
     */
    public File getFile(String pathName) {
        String delimiter = "/cloudDiskAPI/upload/cloud-disk";
        if (pathName.contains(delimiter)) {
            pathName = pathName.split(delimiter)[1];
        }
        File file = new File(filePath + pathName);
        if (file.exists()) {
            return file;
        } else {
            log.error("文件不存在");
            return null;
        }
    }

    /**
     * 获取文件夹
     * 不存在创建一个文件夹
     *
     * @param pathName
     * @return
     */
    public File getFolder(String pathName) {
        String delimiter = "/cloudDiskAPI/upload/cloud-disk";
        if (pathName.contains(delimiter)) {
            pathName = pathName.split(delimiter)[1];
        }
        File folder = new File(filePath + pathName);
        if (!folder.exists()) {
            if (folder.mkdirs()) {
                log.info("文件夹" + folder.getAbsolutePath() + "已创建");
            } else {
                log.error("文件夹创建失败");
            }
        }
        return folder;
    }

    /**
     * 递归压缩文件夹
     *
     * @param folder
     * @param parentFolder
     * @param zipOutputStream
     * @throws Exception
     */
    public void folderToZip(File folder, String parentFolder, ZipOutputStream zipOutputStream) throws Exception {
        File[] files = folder.listFiles();
        if (files != null && files.length > 0) {
            for (File file : files) {
                if (file.isDirectory()) {
                    folderToZip(file, parentFolder + "/" + file.getName(), zipOutputStream);
                } else {
                    ZipEntry zipEntry = new ZipEntry(parentFolder + "/" + file.getName());
                    zipOutputStream.putNextEntry(zipEntry);

                    try (FileInputStream fileInputStream = new FileInputStream(file)) {
                        byte[] buffer = new byte[1024];
                        int len;
                        while ((len = fileInputStream.read(buffer)) > 0) {
                            zipOutputStream.write(buffer, 0, len);
                        }
                    }
                    zipOutputStream.closeEntry();
                }
            }
        } else {
            // If the folder is empty, create an empty folder entry
            ZipEntry zipEntry = new ZipEntry(parentFolder + "/");
            zipOutputStream.putNextEntry(zipEntry);
            zipOutputStream.closeEntry();
        }
    }

    public String getFileName(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        String[] filename = originalFilename.split("\\.");
        return filename[0];
    }

    public String getFileType(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        String[] filename = originalFilename.split("\\.");
        return filename[1];
    }

    public String getFileSize(MultipartFile file) {
        return String.valueOf(file.getSize());
    }

    /**
     * 将文件 复制到该文件下
     *
     * @param pathName
     * @param folderPathName /tmp/文件夹
     */
    public void copyFile(String pathName, String folderPathName,String name) {
        File file = getFile(pathName);
        File folder = getFolder(folderPathName);
        if (file == null) {
            return;
        }
        try (FileInputStream fis = new FileInputStream(file);
             FileOutputStream fos = new FileOutputStream(new File(folder, name))) {

            byte[] buffer = new byte[1024];
            int bytesRead;

            while ((bytesRead = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }

            log.info("文件复制到" + folder.getAbsolutePath());

        } catch (IOException e) {
            e.printStackTrace();
            log.error("文件复制失败" + file.getAbsolutePath());
        }
    }

}
